/**
 * Copyright &copy; 2012-2016 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 */
package com.thinkgem.jeesite.modules.front.web.pay;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import com.thinkgem.jeesite.common.web.BaseController;
import com.thinkgem.jeesite.modules.pay.entity.log.EcPayLog;
import com.thinkgem.jeesite.modules.pay.sdk.AcpService;
import com.thinkgem.jeesite.modules.pay.sdk.LogUtil;
import com.thinkgem.jeesite.modules.pay.sdk.SDKConstants;
import com.thinkgem.jeesite.modules.pay.service.log.EcPayLogService;
import com.thinkgem.jeesite.modules.pay.util.PayUtil;
import com.thinkgem.jeesite.modules.shop.constant.order.ShopOrderConstant;
import com.thinkgem.jeesite.modules.shop.entity.order.ShopOrder;
import com.thinkgem.jeesite.modules.shop.service.order.ShopOrderService;

/**
 * 支付结果响应Controller（FRONT）
 * 
 * @author Egan
 * @version 2016-12-15
 */
@Controller
@RequestMapping(value = "${frontPath}/front/pay/result")
public class ResultController extends BaseController {
	@Autowired 
	EcPayLogService ecPayLogService;
	@Autowired 
	ShopOrderService shopOrderService;
	@RequestMapping(value = "frontRcvResponse")
	public String frontRcvResponse(HttpServletRequest req, HttpServletResponse resp, Model model) {
		String pageResult = "";
		LogUtil.writeLog("FrontRcvResponse前台接收报文返回开始");
		String encoding = req.getParameter(SDKConstants.param_encoding);
		LogUtil.writeLog("返回报文中encoding=[" + encoding + "]");
		if (PayUtil.encoding_UTF8.equalsIgnoreCase(encoding)) {
			pageResult = "/modules/pay/utf8_result";
		} else {
			pageResult = "/modules/pay/gbk_result";
		}
		Map<String, String> respParam = getAllRequestParam(req);

		// 打印请求报文
		LogUtil.printRequestLog(respParam);

		Map<String, String> valideData = null;
		StringBuffer page = new StringBuffer();
		if (null != respParam && !respParam.isEmpty()) {
			Iterator<Entry<String, String>> it = respParam.entrySet().iterator();
			valideData = new HashMap<String, String>(respParam.size());
			
			while (it.hasNext()) {
				Entry<String, String> e = it.next();
				String key = (String) e.getKey();
				String value = (String) e.getValue();
				try {
					value = new String(value.getBytes(encoding), encoding);
				} catch (UnsupportedEncodingException e1) {
					e1.printStackTrace();
				}
				
				page.append("<tr><td width=\"30%\" align=\"right\">" + key + "(" + key + ")</td><td>" + value + "</td></tr>");
				valideData.put(key, value);
			}
			EcPayLog log = new EcPayLog();
			log.setAmount(new BigDecimal(valideData.get("txnAmt")));
			log.setBankId("95516");
			log.setBankName("银联");
			log.setCoNum(valideData.get("orderId"));
			log.setMerChantid(valideData.get("merId"));
			log.setOrgCode(valideData.get("merId"));
			log.setPayTime(valideData.get("txnTime"));
			log.setOrderNo(valideData.get("orderId"));
			log.setPayDate(valideData.get("txnTime"));
			log.setAccDate(valideData.get("txnTime"));
			log.setPayBankCardNo(valideData.get("accNo"));
			log.setPaySeq(valideData.get("queryId"));
			
			//支付成功
			if ("00".equals(valideData.get("respCode"))) {
				log.setPayFlag("1");
			}else {
				log.setPayFlag("2");
			}
			ecPayLogService.save(log);
			ShopOrder order = new ShopOrder();
			order.setCode(valideData.get("orderId"));
			order.setStatus(ShopOrderConstant.ORDER_PAYMENT_DONE);
			shopOrderService.updateOrderForPaySuccess(order);
		}
		
		if (!AcpService.validate(valideData, encoding)) {
			page.append("<tr><td width=\"30%\" align=\"right\">验证签名结果</td><td>失败</td></tr>");
			LogUtil.writeLog("验证签名结果[失败].");
		} else {
			page.append("<tr><td width=\"30%\" align=\"right\">验证签名结果</td><td>成功</td></tr>");
			LogUtil.writeLog("验证签名结果[成功].");
			//System.out.println(valideData.get("orderId")); 其他字段也可用类似方式获取
		}
		req.setAttribute("result", page.toString());
		LogUtil.writeLog("FrontRcvResponse前台接收报文返回结束");
		return pageResult;
	}
	
	/**
	 * 获取请求参数中所有的信息
	 * 
	 * @param request
	 * @return
	 */
	public static Map<String, String> getAllRequestParam(
			final HttpServletRequest request) {
		Map<String, String> res = new HashMap<String, String>();
		Enumeration<?> temp = request.getParameterNames();
		if (null != temp) {
			while (temp.hasMoreElements()) {
				String en = (String) temp.nextElement();
				String value = request.getParameter(en);
				res.put(en, value);
				// 在报文上送时，如果字段的值为空，则不上送<下面的处理为在获取所有参数数据时，判断若值为空，则删除这个字段>
				if (res.get(en) == null || "".equals(res.get(en))) {
					// System.out.println("======为空的字段名===="+en);
					res.remove(en);
				}
			}
		}
		return res;
	}

	@RequestMapping(value = "backRcvResponse")
	public void backRcvResponse(HttpServletRequest req, HttpServletResponse resp, Model model) {
		LogUtil.writeLog("BackRcvResponse接收后台通知开始");
		
		String encoding = req.getParameter(SDKConstants.param_encoding);
		// 获取银联通知服务器发送的后台通知参数
		Map<String, String> reqParam = getAllRequestParam(req);

		LogUtil.printRequestLog(reqParam);

		Map<String, String> valideData = null;
		if (null != reqParam && !reqParam.isEmpty()) {
			Iterator<Entry<String, String>> it = reqParam.entrySet().iterator();
			valideData = new HashMap<String, String>(reqParam.size());
			while (it.hasNext()) {
				Entry<String, String> e = it.next();
				String key = (String) e.getKey();
				String value = (String) e.getValue();
				try {
					value = new String(value.getBytes(encoding), encoding);
				} catch (UnsupportedEncodingException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				valideData.put(key, value);
			}
		}

		//重要！验证签名前不要修改reqParam中的键值对的内容，否则会验签不过
		if (!AcpService.validate(valideData, encoding)) {
			LogUtil.writeLog("验证签名结果[失败].");
			//验签失败，需解决验签问题
		} else {
			LogUtil.writeLog("验证签名结果[成功].");
			//【注：为了安全验签成功才应该写商户的成功处理逻辑】交易成功，更新商户订单状态
			//String orderId =valideData.get("orderId"); 获取后台通知的数据，其他字段也可用类似方式获取
			//String respCode =valideData.get("respCode"); 获取应答码，收到后台通知了respCode的值一般是00，可以不需要根据这个应答码判断。
			
		}
		LogUtil.writeLog("BackRcvResponse接收后台通知结束");
		//返回给银联服务器http 200  状态码
		try {
			resp.getWriter().print("ok");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}